﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Styx;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Styx.Pathing;
using Styx.Common;
using System.Windows.Media;
using Styx.CommonBot.Frames;
using System.Diagnostics;

namespace Guardian
{
    public partial class Combat : CombatRoutine
    {
        Composite BeerRotation()
        {
            return new PrioritySelector(
                Cast(BEAR_FORM, ret => Me.Shapeshift != ShapeshiftForm.Bear),
                new Decorator(ret => Me.HealthPercent <= SettingsBear.myPrefs.PercentHealthstone && nextHealthstoneUseAllowed <= DateTime.Now, HealthstoneBear()),
                new Decorator(ret => gotTarget && AutoBot && UnfriendlyUnits.Count() > 0 && Me.CurrentTarget.Distance >= 12, new Action(ret => { Me.ClearTarget(); return RunStatus.Failure; })),
                new Decorator(ret => !Me.CurrentMap.IsArena
                    && SettingsBear.myPrefs.AutoResTank
                    && (Me.CurrentMap.IsRaid || Me.CurrentMap.IsDungeon || Me.CurrentMap.IsScenario || Me.CurrentMap.IsInstance || Me.GroupInfo.IsInRaid || Me.GroupInfo.IsInParty)
                    && AnyTankNearby 
                    && IsOverlayed(REBIRTH_INT)
                    && !spellOnCooldown(REBIRTH)
                    && nextRebirthAllowed <= DateTime.Now, ResTank()),
                new Decorator(ret => !Me.CurrentMap.IsArena
                    && SettingsBear.myPrefs.AutoResHealer
                    && (Me.CurrentMap.IsRaid || Me.CurrentMap.IsDungeon || Me.CurrentMap.IsScenario || Me.CurrentMap.IsInstance || Me.GroupInfo.IsInRaid || Me.GroupInfo.IsInParty)
                    && AnyHealerNearby 
                    && IsOverlayed(REBIRTH_INT)
                    && !spellOnCooldown(REBIRTH)
                    && nextRebirthAllowed <= DateTime.Now, ResHealer()),
                new Decorator(ret => !spellOnCooldown(HEALING_TOUCH)
                    && Me.HealthPercent >= 90
                    && (Me.CurrentMap.IsRaid 
                    || Me.CurrentMap.IsDungeon 
                    || Me.CurrentMap.IsScenario 
                    || Me.CurrentMap.IsInstance 
                    || Me.CurrentMap.IsArena
                    || Me.CurrentMap.IsBattleground
                    || Me.GroupInfo.IsInRaid 
                    || Me.GroupInfo.IsInParty)
                    && IsOverlayed(HEALING_TOUCH_INT)
                    && nextHealingTouchAllowed <= DateTime.Now, HealPartyMember()),
                new Decorator(ret => !spellOnCooldown(HEALING_TOUCH)
                    && IsOverlayed(HEALING_TOUCH_INT) 
                    && (buffTimeLeft(DREAM_OF_CENARIUS, Me) <= 3000 || Me.HealthPercent <= 90)
                    && nextHealingTouchAllowed <= DateTime.Now, CastHealingTouch()),
                new Decorator(ret => (Me.CurrentTarget == null || Me.CurrentTarget.IsDead || (AutoBot && Me.CurrentTarget.IsFriendly))
                    && AllowTargeting,
                    new Action(ret => { Me.ClearTarget(); FindTarget(); return RunStatus.Failure; })),
                new Decorator(ret => IsRooted(Me), RemoveRooted()),
                new Decorator(ret => gotTarget && AllowTargeting && UnfriendlyUnits.Count() > 0 && AutoBot && Me.CurrentTarget.Distance > 12,
                new Action(ret => { Me.ClearTarget(); FindTarget(); return RunStatus.Failure; })),

                
                //start combat
                new Decorator(ret => gotTarget && !Me.IsAutoAttacking && Me.CurrentTarget.Distance <= myMeleeRange, AutoAttack()),
                Cast("Lightning Shield", ret => Me.Specialization == WoWSpec.DruidGuardian
                    && SpellManager.HasSpell("Lightning Shield")
                    && !Me.HasAura("Lightning Shield")
                    && !spellOnCooldown("Lightning Shield")
                    && LastSpell != "Lightning Shield"),
                Cast("Elusive Brew", ret => Me.Specialization == WoWSpec.DruidGuardian
                    && gotTarget
                    && SpellManager.HasSpell("Elusive Brew")
                    && !spellOnCooldown("Elusive Brew")
                    && Me.HealthPercent <= SettingsBear.myPrefs.PercentElusiveBrew
                    && LastSpell != "Elusive Brew"),
                Cast("Bone Shield", ret => Me.Specialization == WoWSpec.DruidGuardian
                    && SpellManager.HasSpell("Bone Shield")
                    && !spellOnCooldown("Bone Shield")
                    && !Me.HasAura("Bone Shield")
                    && LastSpell != "Bone Shield"),
                Cast("Consecration", ret => Me.Specialization == WoWSpec.DruidGuardian
                    && gotTarget
                    && SpellManager.HasSpell("Consecration")
                    && !spellOnCooldown("Consecration")
                    && (UnfriendlyUnits.Count() > 2 || IsWoWBoss(Me.CurrentTarget))
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != "Consecration"),
                Cast(FAERIE_SWARM, ret => gotTarget
                    && SpellManager.HasSpell(FAERIE_SWARM)
                    && !spellOnCooldown(FAERIE_SWARM)
                    && (!Me.CurrentTarget.HasAura(FAERIE_SWARM) || !Me.CurrentTarget.HasAura("Weakened Armor"))
                    && LastSpell != FAERIE_SWARM),
                Cast(FAERIE_FIRE, ret => gotTarget
                    && SpellManager.HasSpell(FAERIE_FIRE)
                    && !SpellManager.HasSpell(FAERIE_SWARM)
                    && !spellOnCooldown(FAERIE_FIRE)
                    && (!Me.CurrentTarget.HasAura(FAERIE_FIRE) || !Me.CurrentTarget.HasAura("Weakened Armor"))
                    && LastSpell != FAERIE_FIRE),
                new Decorator(ret => gotTarget
                    && SpellManager.HasSpell(SKULL_BASH)
                    && GetSpellCooldown(SKULL_BASH).TotalSeconds < 1
                    && (Me.CurrentTarget.IsCasting && Me.CanInterruptCurrentSpellCast)
                    && nextInterruptAllowed <= DateTime.Now, SkullBash()),
                new Decorator(ret => gotTarget
                    && SpellManager.HasSpell(WAR_STOMP)
                    && !spellOnCooldown(WAR_STOMP)
                    && (Me.CurrentTarget.IsCasting && !Me.CanInterruptCurrentSpellCast)
                    && nextStunAllowed <= DateTime.Now, WarStomp()),
                new Decorator(ret => gotTarget
                    && SpellManager.HasSpell(MIGHTY_BASH)
                    && !spellOnCooldown(MIGHTY_BASH)
                    && (Me.CurrentTarget.IsCasting && !Me.CanInterruptCurrentSpellCast)
                    && nextStunAllowed <= DateTime.Now, MightyBash()),
                Cast(BARKSKIN, ret => gotTarget
                    && !spellOnCooldown(BARKSKIN)
                    && Me.HealthPercent <= SettingsBear.myPrefs.PercentBarkskin
                    && Me.CurrentTarget.IsWithinMeleeRange
                    && LastSpell != BARKSKIN),
                Cast(FRENZIED_REGENERATION, ret => gotTarget
                    && SpellManager.HasSpell(FRENZIED_REGENERATION)
                    && !spellOnCooldown(FRENZIED_REGENERATION)
                    && Me.HealthPercent <= SettingsBear.myPrefs.PercentFrenziedRegeneration
                    && LastSpell != FRENZIED_REGENERATION),
                Cast(SAVAGE_DEFENSE, ret => Me.Specialization == WoWSpec.DruidGuardian
                    && gotTarget
                    && SpellManager.HasSpell(SAVAGE_DEFENSE)
                    && !spellOnCooldown(SAVAGE_DEFENSE)
                    && Me.HealthPercent <= SettingsBear.myPrefs.PercentSavageDefense
                    && Me.RagePercent >= 60
                    && LastSpell != SAVAGE_DEFENSE),
                Cast(SURVIVAL_INSTINCTS, ret => gotTarget
                    && SpellManager.HasSpell(SURVIVAL_INSTINCTS)
                    && !spellOnCooldown(SURVIVAL_INSTINCTS)
                    && Me.HealthPercent <= SettingsBear.myPrefs.PercentSurvivalInstincts
                    && LastSpell != SURVIVAL_INSTINCTS),
                Cast(BERSERK, ret => gotTarget
                     && SpellManager.HasSpell(BERSERK)
                     && !spellOnCooldown(BERSERK)
                     && IsWoWBoss(Me.CurrentTarget)
                     && Me.CurrentTarget.IsWithinMeleeRange
                     && LastSpell != BERSERK),
                new Decorator(ret => SpellManager.HasSpell(FORCE_OF_NATURE)
                    && gotTarget
                    && nextFoNCastAllowed <= DateTime.Now, CastFoN()),
                  Cast(INCARNATION, ret => gotTarget
                      && SpellManager.HasSpell(INCARNATION)
                      && !spellOnCooldown(INCARNATION)
                      && IsWoWBoss(Me.CurrentTarget)
                      && Me.CurrentTarget.IsWithinMeleeRange
                      && LastSpell != INCARNATION),
                  new Decorator(ret => SettingsBear.myPrefs.Trinket1Use != SettingsBear.TrinketsUse.Manual 
                      && nextTrinketTimeAllowed <= DateTime.Now
                      && Me.CurrentTarget.IsWithinMeleeRange, Trinket1()),
                  new Decorator(ret => SettingsBear.myPrefs.Trinket2Use != SettingsBear.TrinketsUse.Manual 
                      && nextTrinketTimeAllowed <= DateTime.Now
                      && Me.CurrentTarget.IsWithinMeleeRange, Trinket2()),
                  new Decorator(ret => gotTarget
                      && SpellManager.HasSpell(LIFEBLOOD)
                      && !spellOnCooldown(LIFEBLOOD)
                      && IsWoWBoss(Me.CurrentTarget)
                      && NotHaveHasteBuffs
                      && Me.CurrentTarget.IsWithinMeleeRange
                      && LastSpell != LIFEBLOOD, LifeBlood()),
                  Cast(BERSERKING, ret => gotTarget
                      && SpellManager.HasSpell(BERSERKING)
                      && !spellOnCooldown(BERSERKING)
                      && IsWoWBoss(Me.CurrentTarget)
                      && NotHaveHasteBuffs
                      && Me.CurrentTarget.IsWithinMeleeRange),
                  new Decorator(ret => gotTarget
                      && (!spellOnCooldown(MANGLE))
                      && nextMangleBearAllowed <= DateTime.Now, CastMangleBear()),
                  new Decorator(ret => gotTarget
                      && !spellOnCooldown(MAUL)
                      && (IsOverlayed(MAUL_INT) || Me.RagePercent >= 70)
                      && nextMaulAllowed <= DateTime.Now, CastMaul()),
                  new Decorator(ret => gotTarget
                      && !PauseAoe
                      && !spellOnCooldown(THRASH) 
                      && !Me.CurrentTarget.HasAura(THRASH)
                      && nextThrashBearAllowed <= DateTime.Now, CastThrashBear()),
                  new Decorator(ret => gotTarget
                      && NeedSwipeBear
                      && !spellOnCooldown(SWIPE)
                      && nextSwipeBearAllowed <= DateTime.Now, CastSwipeBear()),
                  new Decorator(ret => gotTarget
                      && !spellOnCooldown(LACERATE)
                      && nextLacerateAllowed <= DateTime.Now, CastLacerate())
                );
        }

        #region CastLacerate
        private DateTime nextLacerateAllowed;

        public void SetNextLacerateAllowed()
        {
            nextLacerateAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }
        Composite CastLacerate()
        {
            return new Action(ret =>
            {
                if (SpellManager.CanCast(LACERATE))
                {
                    SpellManager.Cast(LACERATE);
                    Logging.Write(Colors.Yellow, LACERATE);
                    SetNextLacerateAllowed();
                    return RunStatus.Success;
                }
                return RunStatus.Failure;
            });
        }
        #endregion

        #region swipe bear
        private DateTime nextSwipeBearAllowed;

        public void SetNextNextSwipeBearAllowed()
        {
            nextSwipeBearAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }
        public bool NeedSwipeBear
        {
            get
            {
                if (!PauseAoe && UnfriendlyUnits.Count() > 1)
                {
                    return true;
                }
                return false;
            }
        }
        Composite CastSwipeBear()
        {
            return new Action(ret =>
            {
                if (SpellManager.CanCast(SWIPE))
                {
                    SpellManager.Cast(SWIPE);
                    Logging.Write(Colors.Yellow, SWIPE);
                    SetNextNextSwipeBearAllowed();
                    return RunStatus.Success;
                }
                return RunStatus.Failure;
            });
        }
        #endregion

        #region Mangle Bear
        private DateTime nextMangleBearAllowed;

        public void SetNextNextMangleBearAllowed()
        {
            nextMangleBearAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }
        Composite CastMangleBear()
        {
            return new Action(ret =>
            {
                if (SpellManager.CanCast(MANGLE))
                {
                    SpellManager.Cast(MANGLE);
                    Logging.Write(Colors.Yellow, MANGLE);
                    SetNextNextMangleBearAllowed();
                    return RunStatus.Success;
                }
                return RunStatus.Failure;
            });
        }
        #endregion

        #region Maul
        private DateTime nextMaulAllowed;

        public void SetNextNextMaulAllowed()
        {
            nextMaulAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }
        Composite CastMaul()
        {
            return new Action(ret =>
            {
                if (SpellManager.CanCast(MAUL))
                {
                    SpellManager.Cast(MAUL);
                    Logging.Write(Colors.Yellow, MAUL);
                    SetNextNextMaulAllowed();
                    return RunStatus.Success;
                }
                return RunStatus.Failure;
            });
        }
        #endregion

        #region thrash Bear
        private DateTime nextThrashBearAllowed;

        public void SetNextNextThrashBearAllowed()
        {
            nextThrashBearAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 1000);
        }

        public bool NeedThrashBear
        {
            get
            {
                if (!SpellManager.HasSpell(THRASH))
                {
                    return false;
                }
                return true;
            }
        }
        Composite CastThrashBear()
        {
            return new Action(ret =>
            {
                if (SpellManager.CanCast(THRASH))
                {
                    SpellManager.Cast(THRASH);
                    Logging.Write(Colors.Yellow, THRASH);
                    SetNextNextThrashBearAllowed();
                    return RunStatus.Success;
                }
                return RunStatus.Failure;
            });
        }
        #endregion
    }
}
